home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / tls / tls007.doc < prev    next >
Text File  |  1994-09-02  |  42KB  |  770 lines

  1. Tcl: An Embeddable Command Language
  2. John K. Ousterhout
  3. Computer Science Division
  4. Electrical Engineering and Computer Sciences
  5. University of California at Berkeley
  6. Berkeley, CA 94720
  7. ouster@sprite.berkeley.edu
  8.  
  9. ABSTRACT
  10.  
  11. Tcl is an interpreter for a tool command language.  It consists of a library
  12. package that is embedded in tools (such as editors, debuggers, etc.) as the
  13. basic command interpreter.  Tcl provides (a) a parser for a simple textual
  14. command language, (b) a collection of built-in utility commands, and (c)
  15. a C interface that tools use to augment the built-in commands with
  16. tool-specific commands.  Tcl is particularly attractive when integrated with
  17. the widget library of a window system: it increases the programmability of
  18. the widgets by providing mechanisms for variables, procedures, expressions,
  19. etc; it allows users to program both the appearance and the actions of
  20. widgets; and it offers a simple but powerful communication mechanism between
  21. interactive programs.
  22.  
  23. The work described here was supported in part by the National Science
  24. Foundation under Grant ECS-8351961.
  25.  
  26. ?
  27. 1.  Introduction
  28.  
  29. Tcl stands for ``tool command language''.  It consists of a library package
  30. that programs can use as the basis for their command languages.  The
  31. development of Tcl was motivated by two observations.  The first observation
  32. is that a general-purpose programmable command language amplifies the power
  33. of a tool by allowing users to write programs in the command language in
  34. order to extend the tool's built-in facilities.  Among the best-known
  35. examples of powerful command languages are those of the UNIX shells [5]
  36. and the Emacs editor [8].  In each case a computing environment of unusual
  37. power has arisen, in large part because of the availability of a pro-
  38. grammable command language.
  39.  
  40. The second motivating observation is that the number of interactive
  41. applications is increasing.  In the timesharing environments of the late
  42. 1970's and early 1980's almost all programs were batch-oriented.  They
  43. were typically invoked using an interactive command shell.  Besides the
  44. shell, only a few other programs needed to be interactive, such as editors
  45. and mailers.  In contrast, the personal workstations used today, with their
  46. raster displays and mice, encourage a different system structure where a
  47. large number of programs are interactive and the most common style of
  48. interaction is to manipulate individual applications directly with a mouse.
  49. Furthermore, the large displays available today make it possible for many
  50. interactive applications to be active at once, whereas this was not practical
  51. with the smaller screens of ten years ago.
  52.  
  53. Unfortunately, few of today's interactive applications have the power of the
  54. shell or Emacs command languages.  Where good command languages exist, they
  55. tend to be tied to specific programs.  Each new interactive application 
  56. requires a new command language to be developed.  In most cases application
  57. programmers do not have the time or inclination to implement a general-purpose
  58. facility (particularly if the application itself is simple), so the resulting
  59. command languages tend to have insufficient power and clumsy syntax.
  60.  
  61. Tcl is an application-independent command language.  It exists as a
  62. C library package that can be used in many different programs.  The
  63. Tcl library provides a parser for a simple but fully programmable command
  64. language.  The library also implements a collection of built-in commands
  65. that provide general-purpose programming constructs such as variables,
  66. lists, expressions, conditionals, looping, and procedures.  Individual
  67. application programs extend the basic Tcl language with application-specific
  68. commands.  The Tcl library also provides a set of utility routines to simplify
  69. the implementation of tool-specific commands.
  70.  
  71. I believe that Tcl is particularly useful in a windowing environment, and that
  72. it provides two advantages.  First, it can be used as a general-purpose
  73. mechanism for programming the interfaces of applications.  If a tool is based
  74. on Tcl, then it should be relatively easy to modify the application's user
  75. interface and to extend the interface with new commands.  Second, and more
  76. important, Tcl provides a uniform framework for communication between tools.
  77. If used uniformly in all tools, Tcl will make it possible for tools to work
  78. together more gracefully than is possible today.  
  79.  
  80. The rest of this paper is organized as follows.  Section 2 describes the
  81. Tcl language as seen by users.  Section 3 discusses how Tcl is used in
  82. applications, including the C-language interface between application
  83. programs and the Tcl library.  Section 4 describes how Tcl can be used
  84. in a windowing environment to customize interface actions and appearances.
  85. Section 5 shows how Tcl can be used as a vehicle for communication between
  86. applications, and why this is important.  Section 6 presents the status
  87. of the Tcl implementation and some preliminary performance measurements.
  88. Section 7 compares Tcl to Lisp, Emacs, and NeWS, and Section 8 concludes
  89. the paper.
  90.  
  91. 2.  The Tcl Language
  92.  
  93. In a sense, the syntax of the Tcl language is unimportant: any programming
  94. language, whether it is C [6], Forth [4], Lisp [1], or Postscript [2],
  95. could provide many of the same programmability and communication advantages
  96. as Tcl.  This suggests that the best implementation approach is to borrow
  97. an existing language and concentrate on providing a convenient framework for
  98. the use of that language.  However, the environment for an embeddable command
  99. language presents an unusual set of constraints on the language, which are
  100. described below.  I eventually decided that a new language designed from
  101. scratch could probably meet the constraints with less implementation effort
  102. than any existing language.
  103.  
  104. Tcl is unusual because it presents two different interfaces: a textual
  105. interface to users who issue Tcl commands, and a procedural interface to the
  106. applications in which it is embedded.  Each of these interfaces must be
  107. simple, powerful, and efficient.  There were four major factors in the
  108. language design: 
  109.  
  110. [1] The language is for commands.
  111.  
  112. Almost all Tcl ``programs'' will be short, many only one line long.  Most
  113. programs will be typed in, executed once or perhaps a few times, and then
  114. discarded.  This suggests that the language should have a simple syntax so
  115. that it is easy to type commands.  Most existing programming languages have
  116. complex syntax; the syntax is helpful when writing long programs but would
  117. be clumsy if used for a command language.
  118.  
  119. [2] The language must be programmable.
  120.  
  121. It should contain general programming constructs such as variables,
  122. procedures, conditionals, and loops, so that users can extend the built-in
  123. command set by writing Tcl procedures.  Extensibility also argues for
  124. a simple syntax: this makes it easier for Tcl programs to generate other
  125. Tcl programs.
  126.  
  127. [3] The language must permit a simple and efficient interpreter.
  128.  
  129. For the Tcl library to be included in many small programs, particularly
  130. on machines without shared-library facilities, the interpreter must not
  131. occupy much memory.  The mechanism for interpreting Tcl commands must be
  132. fast enough to be usable for events that occur hundreds of times a second,
  133. such as mouse motion.
  134.  
  135. [4] The language must permit a simple interface to C applications.
  136.  
  137. It must be easy for C applications to invoke the interpreter and easy
  138. for them to extend the built-in commands with application-specific
  139. commands.  This factor was one of the reasons why I decided not to
  140. use Lisp as the command language: Lisp's basic data types and storage
  141. management mechanisms are so different than those of C that it would
  142. be difficult to build a clean and simple interface between them.
  143.  
  144. For Tcl I used a data type (string) that is natural to C.
  145.  
  146. 2.1.  Tcl Language Syntax
  147.  
  148. Tcl's basic syntax is similar to that of the UNIX shells: a command consists
  149. of one or more fields separated spaces or tabs.  The first field is the name
  150. of a command, which may be either a built-in command, an application-specific
  151. command, or a procedure consisting of a sequence of Tcl commands.  Fields
  152. after the first one are passed to the command as arguments.  Newline
  153. characters are used as command separators, just as in the UNIX shells, and
  154. semi-colons may be used to separate commands on the same line.  Unlike the
  155. UNIX shells, each Tcl command returns a string result, or the empty string
  156. if a return value isn't appropriate.
  157.  
  158. There are four additional syntactic constructs in Tcl, which give the language
  159. a Lisp-like flavor.  Curly braces are used to group complex arguments; they
  160. act as nestable quote characters.  If the first character of an argument is a
  161. open brace, then the argument is not terminated by white space.  Instead, it
  162. is terminated by the matching close brace.  The argument passed to the command
  163. consists of everything between the braces, with the enclosing braces stripped
  164. off.  For example, the command
  165.  
  166.         set a {dog cat {horse cow mule} bear}
  167.  
  168. will receive two arguments: ``a'' and ``dog cat {horse cow mule} bear''.
  169. This particular command will set the variable
  170.         a
  171. to a string equal to the second argument.  If an argument is enclosed
  172. in braces, then none of the other substitutions described below is made
  173. on the argument.  One of the most common uses of braces is to specify a
  174. Tcl subprogram as an argument to a Tcl command.
  175.  
  176. The second syntactic construct in Tcl is square brackets, which are used to
  177. invoke command substitution.  If an open bracket appears in an argument, then
  178. everything from the open bracket up to the matching close bracket is treated
  179. as a command and executed recursively by the Tcl interpreter.  The result of
  180. the command is then substituted into the argument in place of the bracketed
  181. string.  For example, consider the command
  182.  
  183.         set a [format {Santa Claus is %s years old} 99]
  184.  
  185. The format command does printf-like formatting and returns the string
  186. ``Santa Claus is 99 years old'', which is then passed to set and assigned
  187. to variable a.
  188.  
  189. The third syntactic construct is the dollar sign, which is used for variable
  190. substitution.  If it appears in an argument then the following characters are
  191. treated as a variable name; the contents of the variable are substituted into
  192. the argument in place of the dollar sign and name.  For example, the commands
  193.  
  194. set b 99
  195. set a [format {Santa Claus is %s years old} $b]
  196.  
  197. result in the same final value for a as the single command in the previous
  198. paragraph.  Variable substitution isn't strictly necessary since there are 
  199. other ways to achieve the same effect, but it reduces typing.
  200.  
  201. The last syntactic construct is the backslash character, which may be used
  202. to insert special characters into arguments, such as curly braces or
  203. non-printing characters.
  204.  
  205. 2.2.  Data Types
  206.  
  207. There is only one type of data in Tcl: strings.  All commands, arguments
  208. to commands, results returned by commands, and variable values are ASCII
  209. strings.  The use of strings throughout Tcl makes it easy to pass information
  210. back and forth between Tcl library procedures and C code in the enclosing
  211. application.  It also makes it easier to pass Tcl-related information back
  212. and forth between machines of different types.
  213.  
  214. Although everything in Tcl is a string, many commands expect their string
  215. arguments to have particular formats.  There are three particularly common
  216. formats for strings: lists, expressions, and commands.  A list is just a
  217. string containing one or more fields separated by white space, similar to
  218. a command.  Curly braces may be used to enclose complex list elements; these
  219. complex list elements are often lists in their own right, as in Lisp.  For
  220. example, the string
  221.  
  222.         dog cat {horse cow mule} bear
  223.  
  224. is a list with four elements, the third of which is a list with three
  225. elements.  Tcl provides commands for a number of list-manipulation operations,
  226. such as creating lists, extracting elements, and computing list lengths.  
  227.  
  228. The second common form for a string is a numeric expression.  Tcl 
  229. expressions have the same operators and precedence as expressions in C.
  230. The "expr" Tcl command evaluates a string as an expression and returns the
  231. result (as a string, of course).  For example, the command
  232.  
  233. expr {($a < $b) || ($c != 0)}
  234.  
  235. returns ``0'' if the numeric value of variable a is less than that of
  236. variable b, or if variable c is not zero; otherwise it returns
  237. ``0''.  Several other commands, such as "if" and "for", expect one or more 
  238. of their arguments to be expressions.
  239.  
  240. The third common interpretation of strings is as commands (or sequences of
  241. commands).  Arguments of this form are used in Tcl commands that implement
  242. control structures.  For example, consider the following command:
  243.  
  244. if {$a < $b} {
  245.         set tmp $a
  246.         set a $b
  247.         set b $tmp
  248. }
  249.  
  250. The "if" command receives two arguments here, each of which is delimited
  251. by curly braces.  "If" is a built-in command that evaluates its first
  252. argument as an expression; if the result is non-zero, "if" executes its
  253. second argument as a Tcl command.  This particular command swaps the
  254. values of the variables "a" and "b" if "a" is less than "b".
  255.  
  256. Tcl also allows users to define command procedures written in the Tcl
  257. language.  I will refer to these procedures as tclproc's, in order to
  258. distinguish them from other procedures written in C.  The "proc" built-in
  259. command is used to create a tclproc.  For example, here is a Tcl command
  260. that defines a recursive factorial procedure:
  261.  
  262. proc fac x {
  263.         if {$x == 1} {return 1}
  264.         return [expr {$x * [fac [expr $x-1]]}]
  265. }
  266.  
  267. The "proc" command takes three arguments: a name for the new tclproc, a
  268. list of variable names (in this case the list has only a single element,
  269. "x"), and a Tcl command that comprises the body of the tclproc.  Once
  270. this proc command has been executed, "fac" may be invoked just like any
  271. other Tcl command.  For example 
  272.  
  273.     fac 4
  274.     
  275. will return the string ``24''.  
  276.  
  277. Figure 1 lists all of the built-in Tcl commands in groups.  In addition to
  278. the commands already mentioned, Tcl provides commands for manipulating
  279. strings (comparison, matching, and printf/scanf-like operations), commands
  280. for manipulating files and file names, and a command to fork a subprocess
  281. and return the subprocess's standard output as result.  The built-in Tcl
  282. commands provide a simple but complete programming language.  The built-in
  283. facilities may be extended in three ways: by writing tclprocs; by invoking
  284. other programs as subprocesses; or by defining new commands with C
  285. procedures as described in the next section.
  286.  
  287. 3.  Embedding Tcl in Applications
  288.  
  289. Although the built-in Tcl commands could conceivably be used as a
  290. stand-alone programming system, Tcl is really intended to be embedded
  291. in application programs.  I have built several application programs using
  292. Tcl, one of which is a mouse-based editor for X called "mx".  In the rest
  293. of the paper I will use examples from mx to illustrate how Tcl interacts
  294. with its enclosing application.  
  295.  
  296. An application using Tcl extends the built-in commands with a few
  297. additional commands related to that particular application.  For
  298. example, a clock program might provide additional commands to control
  299. how the clock is displayed and to set alarms; the mx editor provides
  300. additional commands to read a file from disk, display it in a window,
  301. select and modify ranges of bytes, and write the modified file back to
  302. disk.  An application programmer need only write the application-specific
  303. commands; the built-in commands provide programmability and extensibility
  304. ``for free''.  To users, the application-specific commands appear the same
  305. as the built-in commands.  
  306.  
  307. Figure 2 shows the relationship between Tcl and the rest of an application.
  308. Tcl is a C library package that is linked with the application.  The Tcl
  309. library includes a parser for the Tcl language, procedures to execute the
  310. built-in commands, and a set of utility procedures for things like expression
  311. evaluation and list management.  The parser includes an extension interface
  312. that may be used to extend the language's command set.
  313.  
  314. To use Tcl, an application first creates an object called an "interpreter",
  315. using the following library procedure:
  316.  
  317.         Tcl_Interp *Tcl_CreateInterp()
  318.  
  319. An interpreter consists of a set of commands, a set of variable bindings,
  320. and a command execution state.  It is the basic unit manipulated by most
  321. of the Tcl library procedures.
  322.  
  323. Simple applications will use only a single interpreter, while more complex
  324. applications may use multiple interpreters for different purposes.  For
  325. example, mx uses one interpreter for each window on the screen.
  326.  
  327. The Tcl library provides a parser for the Tcl language, a set of built-in
  328. commands, and several utility procedures.  The application provides 
  329. application-specific commands plus procedures to collect commands for
  330. execution.  The commands are parsed by Tcl and then passed to relevant
  331. command procedures (either in Tcl or in the application) for execution.
  332.  
  333. Once an application has created an interpreter, it calls the
  334. Tcl_CreateCommand procedure to extend the interpreter with
  335. application-specific commands:
  336.  
  337. typedef int Tcl_CmdProc((ClientData) clientData, Tcl_Interp *interp,
  338.         int argc, char *argv[]);
  339.  
  340. Tcl_CreateCommand(Tcl_Interp *interp, char *name, Tcl_CmdProc proc,
  341.         ClientData clientData)
  342.  
  343. Each call to Tcl_CreateCommand associates a particular command name
  344. (name) with a procedure that implements that command (proc) and an
  345. arbitrary single-word value to pass to that procedure (clientData).
  346.  
  347. After creating application-specific commands, the application enters
  348. a main loop that collects commands and passes them to the Tcl_Eval
  349. procedure for execution:
  350.  
  351.         int Tcl_Eval(Tcl_Interp *interp, char *cmd)
  352.  
  353. In the simplest form, an application might simply read commands from the
  354. terminal or from a file.  In the mx editor Tcl commands are associated
  355. with events such as keystrokes, mouse buttons, or menu activations; each
  356. time an event occurs, the corresponding Tcl command is passed to Tcl_Eval.
  357.  
  358. The Tcl_Eval procedure parses its cmd argument into fields, looks up the
  359. command name in the table of those associated with the interpreter, and
  360. invokes the command procedure associated with that command.  All command
  361. procedures, whether built-in or application-specific, are called in the
  362. same way, as described in the typedef for Tcl_CmdProc above.
  363. A command procedure is passed an array of strings describing the command's
  364. arguments (argc and argv) plus the clientData value that was associated
  365. with the command when it was created.  ClientData is typically a pointer
  366. to an application-specific structure containing information needed to
  367. execute the command.  For example, in mx the clientData argument points
  368. to a per-window data structure describing the file being edited and the
  369. window it is displayed in.
  370.  
  371. Control mechanisms like "if" and "for" are implemented with recursive
  372. calls to Tcl_Eval.  For example, the command procedure for the "if"
  373. command evaluates its first argument as an expression; if the result
  374. is non-zero, then it calls Tcl_Eval recursively to execute its second
  375. argument as a Tcl command.  During the execution of that command, Tcl_Eval
  376. may be called recursively again, and so on.  Tcl_Eval also calls itself
  377. recursively to execute bracketed commands that appear in arguments.
  378.  
  379.  
  380. Even tclprocs such as fac use this same basic mechanism.
  381. When the "proc" command is invoked to create "fac", the proc command
  382. procedure creates a new command by calling Tcl_CreateCommand as
  383. illustrated in Figure 3.  The new command has the name "fac".  Its
  384. command procedure ("proc" in the call to Tcl_CreateCommand) is a
  385. special Tcl library procedure called "InterpProc", and its clientData
  386. is a pointer to a structure describing the tclproc.  This structure
  387. contains, among other things, a copy of the body of the tclproc (the
  388. third argument to the proc command).  When the fac command is invoked,
  389. Tcl_Eval calls InterpProc, which in turn calls Tcl_Eval to execute the
  390. body of the tclproc.  There is some additional code required to associate
  391. the argument of the fac command (which is passed to InterpProc in its argv
  392. array) with the "x" variable used inside fac's body, and to support variables
  393. with local scope, but much of the mechanism for tclprocs is the same as that
  394. for any other Tcl command.
  395.  
  396. The creation and execution of a tclproc (a procedure written in Tcl):
  397. (a) the proc command is invoked, e.g.  to create the fac procedure; (b)
  398. the Tcl parser invokes the command procedure associated with proc; (c)
  399. the proc command procedure creates a data structure to hold the Tcl
  400. command that is fac's body; (d) fac is registered as a new Tcl command,
  401. with InterpProc as its command procedure; (e) fac is invoked as a Tcl
  402. command; (f) the Tcl parser invokes InterpProc as the command procedure
  403. for fac; (g) InterpProc retrieves the body of fac from the data structure;
  404. and (h) the Tcl commands in fac's body are passed back to the Tcl parser
  405. for execution.
  406.  
  407. A Tcl command procedure returns two results to Tcl_Eval: an integer return
  408. code and a string.  The return code is returned as the procedure's result,
  409. and the string is stored in the interpreter, from which it can be retrieved
  410. later.  Tcl_Eval returns the same code and string to its caller.
  411.  
  412. Table I summarizes the return codes and strings.
  413.  
  414. Normally the return code is TCL_OK and the string contains the result of
  415. the command.  If an error occurs in executing a command, then the return
  416. code will be TCL_ERROR and the string will describe the error condition.
  417. When TCL_ERROR is returned (or any value other than TCL_OK), the normal
  418. action is for nested command procedures to return the same code and string
  419. to their callers, unwinding all pending command executions until eventually
  420. the return code and string are returned by the top-level call to Tcl_Eval.
  421. At this point the application will normally display the error message for
  422. the user by printing it on the terminal or displaying it in a notifier
  423. window.  
  424.  
  425. Return codes other than TCL_OK or TCL_ERROR cause partial unwinding.  For
  426. example, the break command returns a TCL_BREAK code.  This causes nested
  427. command executions to be unwound until a nested "for" or "foreach" command
  428. is reached.  When a "for" or "foreach" command invokes Tcl_Eval recursively,
  429. it checks specially for the TCL_BREAK result.  When this occurs the "for" or
  430. "foreach" command terminates the loop, but it doesn't return the TCL_BREAK
  431. code to its caller.  Instead it returns TCL_OK.  Thus no higher levels of
  432. execution are aborted.  The TCL_CONTINUE return code is also handled by the 
  433. "for" and "foreach" commands (they go on to the next loop iteration) and
  434. TCL_RETURN is handled by the InterpProc procedure.  Only a few command
  435. procedures, like "break" and "for", know anything about special return codes
  436. such as TCL_BREAK; other command procedures simply abort whenever they see any
  437. return code other than TCL_OK.
  438.  
  439. The "catch" command may be used to prevent complete unwinding on TCL_ERROR
  440. returns.  Catch takes an argument that is a Tcl command to execute.  It
  441. passes the command to Tcl_Eval for execution, but always returns TCL_OK.
  442. If an error occurs in the command, catch's command procedure detects the
  443. TCL_ERROR return value from Tcl_Eval, saves information about the error
  444. in Tcl variables, and then returns TCL_OK to its caller.  In almost all
  445. cases I think the best response to an error is to abort all command 
  446. invocations and notify the user; catch is provided for those few occasions
  447. where an error is expected and can be handled without aborting.
  448.  
  449. 4.  Tcl and Window Applications
  450.  
  451. An embeddable command language like Tcl offers particular advantages in
  452. a windowing environment.  This is partly because there are many interactive
  453. programs in a windowing environment (hence many places to use a command
  454. language) and partly because configurability is important in today's
  455. windowing environments and a language like Tcl provides the flexibility
  456. to reconfigure.
  457.  
  458. Tcl can be used for two purposes in a window application: to configure the
  459. application's interface actions, and to configure the application's
  460. interface appearance.  These two purposes are discussed in the paragraphs
  461. below.
  462.  
  463. The first use of Tcl is for interface actions.  Ideally, each event that
  464. has any importance to the application should be bound to a Tcl command.
  465. Each keystroke, each mouse motion or mouse button press (or release), and
  466. each menu entry should be associated with a Tcl command.  When the event
  467. occurs, it is first mapped to its Tcl command and then executed by passing
  468. the command to Tcl_Eval.  The application should not take any actions
  469. directly; all actions should first pass through Tcl.  Furthermore, the 
  470. application should provide Tcl commands that allow the user to change the
  471. Tcl command associated with any event.  
  472.  
  473. In interactive windowing applications, the use of Tcl will probably not be
  474. visible to beginning users: they will manipulate the applications using
  475. buttons, menus, and other interface components.  However, if Tcl is used as
  476. an intermediary for all interface actions then two advantages accrue.  First,
  477. it becomes possible to write Tcl programs to reconfigure the interface.
  478. For example, users will be able to rebind keystrokes, change mouse buttons,
  479. or replace an existing operation with a more complex one specified as a set of
  480. Tcl commands or tclprocs.  The second advantage is that this approach forces
  481. all of the application's functionality to be accessible through Tcl: anything
  482. that can be invoked with the mouse or keyboard can also be invoked with Tcl
  483. programs.  This makes it possible to write tclprocs that simulate the actions
  484. of the program, or that compose the program's basic actions into more powerful
  485. actions.  It also permits interactive sessions to be recorded and replayed as
  486. a sequence of Tcl commands (see Section 5).
  487.  
  488. The second use for Tcl in a window application is to configure the appearance
  489. of the application.  All of the application's interface components 
  490. (``widgets'' in X terminology), such as labels, buttons, text entries, menus,
  491. and scrollbars, should be configured using Tcl commands.  For example, in
  492. the case of a button the application (or the button widget code) should provide
  493. Tcl commands to change the button's size and location, its text, its colors,
  494. and the action (a Tcl command, of course) to invoke when the button is
  495. activated.  This makes it possible for users to write Tcl programs to
  496. personalize the layout and appearance of the applications they use.  The most
  497. common use of such reconfigurability would probably be in Tcl command files
  498. read by programs automatically when they start execution.  However, the
  499. Tcl commands could also be used to change an application's appearance while
  500. it is running, if that should prove useful.
  501.  
  502. If Tcl is used as described above, then it could serve as a specification 
  503. language for user interfaces.  User interface editors could be written to 
  504. display widgets and let users re-arrange them and configure attributes such
  505. as colors and associated Tcl commands.  The interface editor could then 
  506. output information about the interface as a Tcl command file to be read by 
  507. the application when it starts up.
  508. Some current interface editors output C code which must then be compiled
  509. into the application [7]; unfortunately this approach requires an
  510. application to be recompiled in order to change its interface (or,
  511. alternatively, it requires a dynamic-code-loading facility).  If Tcl
  512. were used as the interface specification language then no recompilation
  513. would be necessary and a single application binary could support many
  514. different interfaces.
  515.  
  516. 5.  Communication Between Applications
  517.  
  518. The advantages of an embedded command language like Tcl become even
  519. greater if all of the tools in an environment are based on the same
  520. language.  First, users need only learn one basic command language;
  521. to move from one application to another they need only learn the
  522. (few?) application-specific commands for the new application.  Second,
  523. generic interface editors become possible, as described in the previous
  524. section.  Third, and most important in my view, Tcl can provide a means
  525. of communication between applications.
  526.  
  527. I have implemented a communication mechanism for X11 in the form of an
  528. additional Tcl command called "send".  For send to work, each Tcl
  529. interpreter associated with an X11 application is given a textual name,
  530. such as "xmh" for an X mail handler or mx.foo.c for a window in which
  531. mx is displaying a file named foo.c.  The send command takes two arguments:
  532. the name of an interpreter and a Tcl command to execute in that interpreter.
  533. "Send" arranges for the command to be passed to the process containing the
  534. named interpreter; the command is executed by that interpreter and the
  535. results (return code and string) are returned to the application that
  536. issued the "send" command.
  537.  
  538. The X11 implementation of send uses a special property attached to the
  539. root window.  The property stores the names of all the interpreters plus
  540. a window identifier for each interpreter.  A command is sent to an interpreter
  541. by appending it to a particular property in the interpreter's associated
  542. window.  The property change is detected by the process that owns the
  543. interpreter; it reads the property, executes the command, and appends
  544. result information onto a property associated with the sending application.
  545. Finally, the sending application detects this change of property, reads
  546. the result information, and returns it as the result of the send command.
  547.  
  548. The send command provides a powerful way for one application to control
  549. another.  For example, a debugger could send commands to an editor to
  550. highlight the current source line as it single-steps through a program.
  551. Or, a user interface editor could use send to manipulate an application's
  552. interface directly: rather than modifying a dummy version of the
  553. application's interface displayed by the interface editor, the interface
  554. editor could use send to modify the interface of a ``live'' application,
  555. while also saving the configuration for a configuration file.  This would
  556. allow an interface designer to try out the look and feel of a new interface
  557. incrementally as changes are made to the interface.
  558.  
  559. Another example of using send is for changing user preferences.  If one
  560. user walks up to a display that has been configured for some other user,
  561. the new user could run a program that finds out about all the existing
  562. applications on the screen (by querying the property that contains their
  563. names), reads the new user's configuration file for each application, and
  564. sends commands to that application to reconfigure it for the new user's
  565. preferences.  When the old user returns, he or she could invoke the same
  566. program to restore the original preferences.
  567.  
  568. "Send" could also be used to record interactive sessions involving multiple
  569. applications and then replay the sessions later (e.g.  for demonstration
  570. purposes).  This would require an additional Tcl command called trace;
  571. trace would take a single argument (a Tcl command string) and cause that
  572. command string to be executed before each other command was executed in
  573. that interpreter.  Within a single application, trace could be used to record
  574. each Tcl command before it is executed, so that the commands could be replayed
  575. later.  In a multi-application environment, a recorder program could be built
  576. using send.  The recorder sends a trace command to each application to be
  577. recorded.  The trace command arranges for information to be sent back
  578. to the recorder about each command executed in that application.  The
  579. recorder then logs information about which applications executed which
  580. commands.  The recorder can reexecute the commands by "send"-ing them
  581. back to the applications again.  The trace command does not yet exist
  582. in Tcl, but it could easily be added.
  583.  
  584. Send provides a much more powerful mechanism for communication between
  585. applications than is available today.  The only easy-to-use form of
  586. communication for today's applications is the selection or cut buffer:
  587. a single string of text that may be set by one application and read by
  588. another.  Send provides a more general form of communication akin to
  589. remote procedure call [3].  If all of an application's functionality is
  590. made available through Tcl, as described in Section 4, then send makes
  591. all of each application's functionality available to other applications
  592. as well.
  593.  
  594. If Tcl (and send) were to become widely used in window applications, I
  595. believe that a better kind of interactive environment would arise,
  596. consisting of a large number of small specialized applications rather
  597. than a few monolithic ones.  Today's applications cannot communicate
  598. with each other very well, so each application must incorporate all
  599. the functionality that it needs.  For example, some window-based debuggers
  600. contain built-in text editors so that they can highlight the current
  601. point of execution.  With Tcl and send, the debugger and the editor could
  602. be distinct programs, with each sending commands to the other as necessary.
  603. Ideally, monolithic applications could be replaced by lots of small
  604. applications that work together in exciting new ways, just as the UNIX
  605. shells allowed lots of small text processing applications to be combined
  606. together.  I think that Tcl, or some other language like it, will provide
  607. the glue that binds together the windowing applications of the 1990's.
  608.  
  609. 6.  Status and Performance
  610.  
  611. The Tcl language was designed in the fall of 1987 and implemented in the
  612. winter of 1988.  In the spring of 1988 I incorporated Tcl into the mx
  613. editor (which already existed, but with an inferior command language),
  614. and also into a companion terminal emulator called Tx.  Both of these
  615. programs have been in use by a small user community at Berkeley for
  616. the last year and a half.  All of the Tcl language facilities exist as
  617. described above, except that the send command is still in prototype form
  618. and trace hasn't been implemented.  Some of the features described in
  619. Section 4, such as menu and keystroke bindings, are implemented in mx, but
  620. in an ad hoc fashion: Tcl is not yet integrated with a widget set.  I am
  621. currently building a new toolkit and widget set that is based entirely on
  622. Tcl.  When it is completed, I expect it to provide all of the features
  623. described in Section 4.  As of this writing, the implementation has barely
  624. begun.
  625.  
  626. Table II shows how long it takes Tcl to execute various commands on two
  627. different workstations.  On Sun-3 workstations, the average time for simple
  628. commands is about 500 microseconds, while on DECstation 3100's the average
  629. time per command is about 160 microseconds.  Although mx does not currently
  630. use a Tcl command for each mouse motion event, the times in Table II suggest
  631. that this would be possible, even on Sun-3 workstations, without significant
  632. degradation of response.  For example, if mouse motion events occur 100 times
  633. per second, the Tcl overhead for dispatching one command per event will
  634. consume only about 1-2% of a Sun-3 processor.
  635. For the ways in which Tcl is currently used (keystroke and menu bindings
  636. consisting of a few commands), there are no noticeable delays associated
  637. with Tcl.  For application-specific commands such as those for the mx editor,
  638. the time to execute the command is much greater than the time required by
  639. Tcl to parse it and call the command procedure.  
  640.  
  641. The Tcl library is small enough to be used in a wide variety of programs, even
  642. on systems without mechanisms for sharing libraries.  The Tcl code consists of 
  643. about 7000 lines of C code (about half of which is comments).  When compiled
  644. for a Motorola 68000, it generates about 27000 bytes of object code.
  645.  
  646. 7.  Comparisons
  647.  
  648. The Tcl language has quite a bit of surface similarity to Lisp, except
  649. that Tcl uses curly braces or brackets instead of parentheses and no braces
  650. are needed around the outermost level of a command.  The greatest difference
  651. between Tcl and Lisp is that Lisp evaluates arguments by default, whereas
  652. in Tcl arguments are not evaluated unless surrounded by brackets.  This
  653. means that more typing effort is required in Tcl if an argument is to be
  654. evaluated, and more typing effort is required in Lisp if an argument is
  655. to be quoted (not evaluated).
  656. It appeared to me that no-evaluation is usually the desired result in
  657. arguments to a command language, so I made this the default in Tcl.
  658. Tcl also has fewer data types than Lisp; this was done in order to simplify
  659. the interface between the Tcl library and an enclosing C application.  
  660.  
  661. The Emacs editor is similar to Tcl in that it provides a framework that
  662. can be used to control many different application programs.  For example,
  663. subprocesses can be run in Emacs windows and users can write Emacs command
  664. scripts that (a) generate command sequences for input to the applications
  665. and (b) re-format the output of applications.  This allows users to embellish
  666. the basic facilities of applications, edit their output, and so on.
  667.  
  668. The difference between Emacs and Tcl is that the programmability is
  669. centralized in Emacs: applications cannot talk to each other unless Emacs
  670. acts as intermediary (e.g.  to set up a new communication mechanism between
  671. two applications, code must be written in Emacs to pass information back
  672. and forth between the applications).  The Tcl approach is decentralized:
  673. each application has its own command interpreter and applications may
  674. communicate directly with each other.
  675.  
  676. Lastly, it is interesting to compare Tcl to NeWS [9], a window system that
  677. is based on the Postscript language.  NeWS allows applications to down-load
  678. a window server in order to change the user interface and modify other
  679. aspects of the system.  In a sense, this is similar to the "send" command in
  680. Tcl, in that applications may send programs to the server for execution.
  681. However, the NeWS mechanism is less general than Tcl: NeWS applications
  682. generate Postscript programs as output but they do not necessarily respond
  683. to Postscript programs as input.  In other words, NeWS applications can
  684. affect each others' interfaces, by controlling the server, but they cannot
  685. directly invoke each others' application-specific operations as they can
  686. with Tcl.
  687.  
  688. To summarize, the Tcl approach is less centralized than either the Emacs
  689. or NeWS approaches.  For a windowing environment with large numbers of
  690. independent tools, I think the decentralized approach makes sense.
  691. In fairness to Emacs, it's important to point out that Emacs wasn't designed
  692. for this environment, and that Emacs works quite nicely in the environment
  693. for which it was designed (ASCII terminals with batch-style applications).
  694. It's also worth noting that direct communication between applications was
  695. not an explicit goal of the NeWS system design.
  696.  
  697. 8.  Conclusions
  698.  
  699. I think that Tcl could improve our interactive environments in three general
  700. ways.  First, Tcl can be used to improve individual tools by providing them
  701. with a programmable command language; this allows users to customize tools
  702. and extend their functionality.  Second, Tcl can provide a uniform command 
  703. language across a range of tools; this makes it easier for users to program 
  704. the tools and also allows tool-independent facilities to be built, such as 
  705. interface editors.  Third, Tcl provides a mechanism for tools to control
  706. each other; this encourages a more modular approach to windowing applications
  707. and makes it possible to re-use old applications in new ways.  In my opinion
  708. the third benefit is potentially the most important.  
  709.  
  710. My experiences with Tcl so far are positive but limited.  Tcl needs a larger
  711. user community and a more complete integration into a windowing toolkit before
  712. it can be fully evaluated.  The Tcl library source code is currently available
  713. to the public in a free, unlicensed form, and I hope to produce a Tcl-based
  714. toolkit in the near future.
  715.  
  716. 9.  Acknowledgments
  717.  
  718. The members of the Sprite project acted as guinea pigs for the editor and
  719. terminal emulator based on Tcl; without their help the language would
  720. not have evolved to its current state.  Fred Douglis, John Hartman,
  721. Ken Shirriff, and Brent Welch provided helpful comments that improved the
  722. presentation of this paper.
  723.  
  724. 10.  References
  725.  
  726. [1] Abelson, H.  and Sussman, G.J.
  727.         Structure and Interpretation of Computer Programs,
  728.         MIT Press, Cambridge, MA, 1985.
  729.  
  730. [2] Adobe Systems, Inc.
  731.         Postscript Language Tutorial and Cookbook,
  732.         Addison-Wesley, Reading, MA, 1985.
  733.  
  734. [3] Birrell, A.  and Nelson, B.  
  735.         ``Implementing Remote Procedure Calls.''
  736.         ACM Transactions on Computer Systems,
  737.         Vol.  2, No.  1, February 1986, pp.  39-59.
  738.  
  739. [4] Brodie, L.
  740.         Starting FORTH: An Introduction to the FORTH Language and
  741.                 Operating System for Beginners and Professionals,
  742.         Prentice Hall, Englewood Cliffs, NJ, 1981.
  743.  
  744. [5] Kernighan, B.W.  and Pike, R.
  745.         The UNIX Programming Environment,
  746.         Prentice Hall, Englewood Cliffs, NJ, 1984.
  747.  
  748. [6] Kernighan, B.W.  and Ritchie, D.M.
  749.         The C Programming Language,
  750.         Second Edition,
  751.         Prentice Hall, Englewood Cliffs, NJ, 1988.
  752.  
  753. [7] Mackey, K., Downs, M., Duffy, J., and Leege, J.
  754.         ``An Interactive Interface Builder for Use with Ada Programs,''
  755.         Xhibition Conference Proceedings, 1989.
  756.  
  757. [8] Stallman, R.
  758.         GNU Emacs Manual,
  759.         Fourth Edition,
  760.         Version 17,
  761.         February 1986.
  762.  
  763. [9] Sun Microsystems, Inc.
  764.         NeWS Technical Overview,
  765.         Sun Microsystems, Inc.
  766.         PN 800-1498-05, 1987.
  767.  
  768.  
  769.                                                                                 
  770.